$libfx0 = @"
    [StructLayout(LayoutKind.Sequential)]
    public struct Nag_Comm
    {
      public int flag;
    };
    public delegate void  NAG_E04UCC_FUN (int array_length, IntPtr a, 
                                                       ref Nag_Comm comm);
    [DllImport("libfx0.dll", CharSet=CharSet.Auto, SetLastError=true)]
        public static extern void CallbackWithStruct(NAG_E04UCC_FUN f , 
                    int array_length, double [] a, ref Nag_Comm user_commt);
"@ 

Add-Type -MemberDefinition $libfx0 -Namespace fx0 -Name "st_fx"

Function SetUnsafeArray([IntPtr]$UnsafeArray, [int]$N, [int]$SetIndex, [double]$NewVal)
{
    $_ARRAY = New-Object double[] $N;
    ### 从非托管数组[IntPtr]复制数据到一维托管数组double[]
    [System.Runtime.InteropServices.Marshal]::Copy($UnsafeArray, $_ARRAY, 0, $N)
    ### 托管数组中操作改变的元素值
    $_ARRAY[$SetIndex] = $NewVal    
    ### 从一维托管数组double[]复制数据到非托管数组[IntPtr]
    [System.Runtime.InteropServices.Marshal]::Copy($_ARRAY, 0, $UnsafeArray, $N)
}

Function GetUnsafeArray([IntPtr]$UnsafeArray, [int]$N)
{
    $_ARRAY = New-Object double[] $N; 
    [System.Runtime.InteropServices.Marshal]::Copy($UnsafeArray, $_ARRAY, 0, $N)
    for($i=0;$i-lt$N;$i++){ 
        Write-Host -NoNewLine $_ARRAY[$i]
        if($i -ne $N-1){
            Write-Host -NoNewline ", "
        }else{
            Write-Host
        }
    }
}

Function GetArray([double[]]$Array)
{
    for($i=0;$i-lt$Array.GetLength(0);$i++){ 
        Write-Host -NoNewLine $ARRAY[$i]
        if($i -ne $N-1){
            Write-Host -NoNewline ", "
        }else{
            Write-Host
        }
    }
}

Function funct([int]$n, [IntPtr]$xptr, [ref]$UserComm)
{
    ### 标记为引用的结构体中的变量不能在ScriptBlock作用域内被访问
    ### 可以在C触发函数中被单独访问
    Write-Host -NoNewLine "In PWSH Function, Original double[]: ";GetUnsafeArray $xptr $n
    SetUnsafeArray $xptr 5 3 0.7
    Write-Host -NoNewLine "In PWSH Function,     Proc double[]: ";GetUnsafeArray $xptr $n
}

### 数组赋初始值
[double[]]$a=@(1.0, 2.0, 3.0, 4.0, 5.0);

[int]$array_length=$a.GetLength(0)
$user_comm=New-Object fx0.st_fx+Nag_Comm;
[fx0.st_fx+NAG_E04UCC_FUN]$F=${function:funct};

$user_comm.flag=99
[fx0.st_fx]::CallbackWithStruct($F, $array_length, $a, [ref]$user_comm)
Write-Host -NoNewLine "Out of PWSH Function, Proc double[]: ";GetArray $a
